#define IMPLEMENT_VEC_OP2(CTYPE) \
    IMPLEMENT_ANY_OP2(,CTYPE)

#define REGISTER_OP2(OPNAME,TYPE,CTYPE) \
    registerFusion(#OPNAME,typeName<CTYPE>::name(),new FusionPoint_##OPNAME##_##CTYPE());

#if DAS_FUSION>=2

#define IMPLEMENT_OP2_INTEGER(OPNAME) \
    IMPLEMENT_ANY_OP2(__forceinline,OPNAME,Int,int32_t); \
    IMPLEMENT_ANY_OP2(__forceinline,OPNAME,UInt,uint32_t); \
    IMPLEMENT_ANY_OP2(_msc_inline_bug,OPNAME,Int64,int64_t); \
    IMPLEMENT_ANY_OP2(_msc_inline_bug,OPNAME,UInt64,uint64_t);

#define IMPLEMENT_OP2_NUMERIC(OPNAME) \
    IMPLEMENT_OP2_INTEGER(OPNAME); \
    IMPLEMENT_ANY_OP2(__forceinline,OPNAME,Float,float); \
    IMPLEMENT_ANY_OP2(__forceinline,OPNAME,Double,double);

#else

#define IMPLEMENT_OP2_INTEGER(OPNAME) \
    IMPLEMENT_ANY_OP2(__forceinline,OPNAME,Int,int32_t); \
    IMPLEMENT_ANY_OP2(__forceinline,OPNAME,UInt,uint32_t);

#define IMPLEMENT_OP2_NUMERIC(OPNAME) \
    IMPLEMENT_OP2_INTEGER(OPNAME); \
    IMPLEMENT_ANY_OP2(__forceinline,OPNAME,Float,float);

#endif

#define IMPLEMENT_OP2_SCALAR(OPNAME) \
    IMPLEMENT_ANY_OP2(__forceinline,OPNAME,Bool,bool); \
    IMPLEMENT_OP2_NUMERIC(OPNAME);

#define IMPLEMENT_OP2_WORKHORSE(OPNAME) \
    IMPLEMENT_ANY_OP2(__forceinline,OPNAME,Ptr,StringPtr); \
    IMPLEMENT_ANY_OP2(__forceinline,OPNAME,Ptr,VoidPtr); \
    IMPLEMENT_OP2_SCALAR(OPNAME);

#if DAS_FUSION>=2

#define REGISTER_OP2_INTEGER(OPNAME) \
    REGISTER_OP2(OPNAME,Int,int32_t); \
    REGISTER_OP2(OPNAME,UInt,uint32_t); \
    REGISTER_OP2(OPNAME,Int64,int64_t); \
    REGISTER_OP2(OPNAME,UInt64,uint64_t);

#define REGISTER_OP2_NUMERIC(OPNAME) \
    REGISTER_OP2_INTEGER(OPNAME); \
    REGISTER_OP2(OPNAME,Float,float); \
    REGISTER_OP2(OPNAME,Double,double);

#else

#define REGISTER_OP2_INTEGER(OPNAME) \
    REGISTER_OP2(OPNAME,Int,int32_t); \
    REGISTER_OP2(OPNAME,UInt,uint32_t);

#define REGISTER_OP2_NUMERIC(OPNAME) \
    REGISTER_OP2_INTEGER(OPNAME); \
    REGISTER_OP2(OPNAME,Float,float);

#endif

#define REGISTER_OP2_SCALAR(OPNAME) \
    REGISTER_OP2(OPNAME,Bool,bool); \
    REGISTER_OP2_NUMERIC(OPNAME);

#define REGISTER_OP2_WORKHORSE(OPNAME) \
    REGISTER_OP2(OPNAME,Ptr,StringPtr); \
    REGISTER_OP2(OPNAME,Ptr,VoidPtr); \
    REGISTER_OP2_SCALAR(OPNAME);

#define IMPLEMENT_OP2_VEC(OPNAME,CTYPE) \
    IMPLEMENT_ANY_OP2(__forceinline,OPNAME,,CTYPE)

#define IMPLEMENT_OP2_INTEGER_VEC(OPNAME) \
    IMPLEMENT_OP2_VEC(OPNAME,int2 ); \
    IMPLEMENT_OP2_VEC(OPNAME,uint2); \
    IMPLEMENT_OP2_VEC(OPNAME,int3 ); \
    IMPLEMENT_OP2_VEC(OPNAME,uint3); \
    IMPLEMENT_OP2_VEC(OPNAME,int4 ); \
    IMPLEMENT_OP2_VEC(OPNAME,uint4);

#define IMPLEMENT_OP2_NUMERIC_VEC(OPNAME)  \
    IMPLEMENT_OP2_INTEGER_VEC(OPNAME); \
    IMPLEMENT_OP2_VEC(OPNAME,float2 ); \
    IMPLEMENT_OP2_VEC(OPNAME,float3 ); \
    IMPLEMENT_OP2_VEC(OPNAME,float4 );

#define REGISTER_OP2_VEC(OPNAME,CTYPE) \
    REGISTER_OP2(OPNAME,,CTYPE)

#define REGISTER_OP2_INTEGER_VEC(OPNAME) \
    REGISTER_OP2_VEC(OPNAME,int2 ); \
    REGISTER_OP2_VEC(OPNAME,uint2); \
    REGISTER_OP2_VEC(OPNAME,int3 ); \
    REGISTER_OP2_VEC(OPNAME,uint3); \
    REGISTER_OP2_VEC(OPNAME,int4 ); \
    REGISTER_OP2_VEC(OPNAME,uint4);

#define REGISTER_OP2_NUMERIC_VEC(OPNAME) \
    REGISTER_OP2_INTEGER_VEC(OPNAME); \
    REGISTER_OP2_VEC(OPNAME,float2 ); \
    REGISTER_OP2_VEC(OPNAME,float3 ); \
    REGISTER_OP2_VEC(OPNAME,float4 );

